package com.topisv.tms.service.occupiedArea;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.topisv.tms.entity.occupiedArea.StockTypeCostConfig;
import com.topisv.tms.entity.occupiedArea.StockTypeMapping;
import com.topisv.tms.entity.stock.CusStock;
import com.topisv.tms.repository.ProcessLogDao;
import com.topisv.tms.repository.occupiedArea.StockTypeCostConfigDao;
import com.topisv.tms.repository.occupiedArea.StockTypeMappingDao;
import com.topisv.tms.service.account.ShiroDbRealm.ShiroUser;

/**
 * 库位类型成本配置_service
 * 
 * @author gh
 * 
 */
@Component
@Transactional(readOnly = true)
public class StockTypeCostConfigService {
	private static final Logger logger = LoggerFactory.getLogger(StockTypeCostConfigService.class);
	@Autowired
	private StockTypeCostConfigDao stccDao;
	@Autowired
	private StockTypeMappingDao stmDao;
	@Autowired
	private ProcessLogDao processLogDao;
	@PersistenceContext
	private EntityManager em;
	
	@Transactional(readOnly = false)
	public void save(StockTypeCostConfig stcc){
		stccDao.save(stcc);
	}
	
	public Page<StockTypeCostConfig> findTable(final StockTypeCostConfig config,int pageNumber,int pageSize){
		Sort sort = new Sort(Direction.DESC, "warehouseCode","createTime");
		PageRequest pageRequest = new PageRequest(pageNumber-1, pageSize,sort);
		return stccDao.findAll(new Specification<StockTypeCostConfig>() {
			@Override
			public Predicate toPredicate(Root<StockTypeCostConfig> r, CriteriaQuery<?> q, CriteriaBuilder cb) {
				Predicate pre = cb.conjunction();
				if (StringUtils.isNotBlank(config.getWarehouseCode())) {
					pre.getExpressions().add(cb.equal(r.<String> get("warehouseCode"), config.getWarehouseCode()));
				}
				return pre;
			}

		},pageRequest);
	}
	
	
	public List<CusStock> findUnassignStockType(StockTypeCostConfig config){
		StringBuffer sql = new StringBuffer("SELECT DISTINCT c.stock_code,c.warehouse_code FROM cus_stock c  WHERE 1 = 1");
		if(StringUtils.isNotEmpty(config.getWarehouseCode())){
			sql.append(" AND c.warehouse_code = ? ");
		}
		sql.append(" AND NOT EXISTS ( SELECT 1 FROM stock_type_mapping s WHERE c.warehouse_code = s.warehouse_code AND s.stock_code = c.stock_code)");
		sql.append(" ORDER BY c.warehouse_code ASC,c.stock_code,c.box_code DESC ");
		
		Query querySql = em.createNativeQuery(sql.toString());
		int index = 1;
		if(StringUtils.isNotEmpty(config.getWarehouseCode())){
			querySql.setParameter(index++, config.getWarehouseCode());
		}
		List<Object[]> rsList = querySql.getResultList();
		List<CusStock> csList = new ArrayList<CusStock>();
		for (Object[] list : rsList) {
			CusStock cs = new CusStock();
			cs.setOrderNum(0);
			cs.setTransportNum(0);
			cs.setUnusedNum(0);
			cs.setSalesNum(0);
			cs.setAirNum(0);
			cs.setLockedNum(0);
			cs.setStockCode((String)list[0]);
			cs.setWarehouseCode((String)list[1]);
			csList.add(cs);
		}
		return csList;
	}
	
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public void saveMapping(String assignStockCodes,StockTypeCostConfig config){
		logger.info("删除stockType");
		stmDao.deleteByStockType(config.getStockType());
		
		ShiroUser user = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
		List<StockTypeMapping> mappingList = new ArrayList<StockTypeMapping>();
		for(String str:assignStockCodes.split(",")){
			if(StringUtils.isNotEmpty(str)){
				StockTypeMapping mapping = new StockTypeMapping();
				mapping.setStockCode(str);
				mapping.setStockType(config.getStockType());
				mapping.setWarehouseCode(config.getWarehouseCode());
				mapping.setStockCost(config.getStockCost());
				mapping.setCreateBy(user.getJobuuid());
				mapping.setCreateTime(new Date());
				mappingList.add(mapping);
			}
		}
		stmDao.save(mappingList);
	}
	
	public List<StockTypeMapping> findAssignStockType(StockTypeCostConfig config){
		return stmDao.findByStockType(config.getStockType());
	}
	
	public StockTypeCostConfig findById(Long id){
		return stccDao.findOne(id);
	}
	
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public void delete(Long id) throws Exception{
		StockTypeCostConfig stcc = stccDao.findOne(id);
		if(stcc==null){
			throw new Exception("数据主键丢失");
		}
		stccDao.delete(id);
		stmDao.deleteByStockType(stcc.getStockType());
	}

	
	
}